package erfgame.core.world;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import erfgame.core.Dimensions3D;

public class WorldGenerationParameters {

	private PropertyChangeSupport support;
	
	private Dimensions3D blockDimensions;
	private Dimensions3D worldBlocks;
	private int gridDiagonal;
	private String worldName;

	private LongitudinalZone northernmostZone;
	private LongitudinalZone southernmostZone;
	
	private Frequency volcanicActivity;
	private int numberOfTectonicPlates;
	
	private int startingLandLevel;
	private int seaLevel;
	
	private long ageOfEarthDuration;
	private long ageOfPlantsDuration;
	private long ageOfAnimalsDuration;
	private long ageOfManDuration;
	
	private List<TerrainMaterialTypeWeight> terrainTypeWeights;
	
	public WorldGenerationParameters() {
		 this( new ArrayList<TerrainMaterialTypeWeight>() );
	}
	
	public WorldGenerationParameters( List<TerrainMaterialTypeWeight> terrainTypeWeights ) {
		this.support = new PropertyChangeSupport( this );
		this.terrainTypeWeights = terrainTypeWeights;
	}

	public Dimensions3D getBlockDimensions() {
		return blockDimensions;
	}

	public void setBlockDimensions(Dimensions3D blockDimensions) {
		support.firePropertyChange(
				"blockDimensions", 
				this.blockDimensions, 
				this.blockDimensions = blockDimensions
		);
	}

	public Dimensions3D getWorldBlocks() {
		return worldBlocks;
	}

	public void setWorldBlocks(Dimensions3D worldBlocks) {
		support.firePropertyChange(
				"worldBlocks", 
				this.worldBlocks, 
				this.worldBlocks = worldBlocks
		);
	}

	public int getGridDiagonal() {
		return gridDiagonal;
	}

	public void setGridDiagonal(int gridDiagonal) {
		support.firePropertyChange(
				"gridDiagonal", 
				this.gridDiagonal, 
				this.gridDiagonal = gridDiagonal
		);
	}

	public String getWorldName() {
		return worldName;
	}

	public void setWorldName(String worldName) {
		support.firePropertyChange(
				"worldName", 
				this.worldName, 
				this.worldName = worldName
		);
	}

	public LongitudinalZone getNorthernmostZone() {
		return northernmostZone;
	}

	public void setNorthernmostZone(LongitudinalZone northernmostZone) {
		support.firePropertyChange(
				"northernmostZone", 
				this.northernmostZone,
				this.northernmostZone = northernmostZone
		);
	}

	public LongitudinalZone getSouthernmostZone() {
		return southernmostZone;
	}

	public void setSouthernmostZone(LongitudinalZone southernmostZone) {
		support.firePropertyChange(
				"southernmostZone", 
				this.southernmostZone, 
				this.southernmostZone = southernmostZone
		);
	}

	public Frequency getVolcanicActivity() {
		return volcanicActivity;
	}

	public void setVolcanicActivity(Frequency volcanicActivity) {
		support.firePropertyChange(
				"volcanicActivity",
				this.volcanicActivity,
				this.volcanicActivity = volcanicActivity
		);
	}

	public int getNumberOfTectonicPlates() {
		return numberOfTectonicPlates;
	}

	public void setNumberOfTectonicPlates(int numberOfTectonicPlates) {
		support.firePropertyChange(
				"numberOfTectonicPlates",
				this.numberOfTectonicPlates,
				this.numberOfTectonicPlates = numberOfTectonicPlates
		);
	}

	public int getStartingLandLevel() {
		return startingLandLevel;
	}

	public void setStartingLandLevel(int startingLandLevel) {
		support.firePropertyChange(
				"startingLandLevel", 
				this.startingLandLevel, 
				this.startingLandLevel = startingLandLevel
		);
	}

	public long getAgeOfEarthDuration() {
		return ageOfEarthDuration;
	}

	public void setAgeOfEarthDuration(long ageOfEarthDuration) {
		long oldTotalDuration = getTotalDuration();
		support.firePropertyChange(
				"ageOfEarthDuration", 
				this.ageOfEarthDuration, 
				this.ageOfEarthDuration = ageOfEarthDuration
		);
		support.firePropertyChange(
				"totalDuration", 
				oldTotalDuration, 
				getTotalDuration()
		);
	}

	public long getAgeOfPlantsDuration() {
		return ageOfPlantsDuration;
	}

	public void setAgeOfPlantsDuration(long ageOfPlantsDuration) {
		long oldTotalDuration = getTotalDuration();
		support.firePropertyChange(
				"ageOfPlantsDuration", 
				this.ageOfPlantsDuration, 
				this.ageOfPlantsDuration = ageOfPlantsDuration
		);
		support.firePropertyChange(
				"totalDuration", 
				oldTotalDuration, 
				getTotalDuration()
		);
	}

	public long getAgeOfAnimalsDuration() {
		return ageOfAnimalsDuration;
	}

	public void setAgeOfAnimalsDuration(long ageOfAnimalsDuration) {
		long oldTotalDuration = getTotalDuration();
		support.firePropertyChange(
				"ageOfAnimalsDuration", 
				this.ageOfAnimalsDuration, 
				this.ageOfAnimalsDuration = ageOfAnimalsDuration
		);
		support.firePropertyChange(
				"totalDuration", 
				oldTotalDuration, 
				getTotalDuration()
		);
	}

	public long getAgeOfManDuration() {
		return ageOfManDuration;
	}

	public void setAgeOfManDuration(long ageOfManDuration) {
		long oldTotalDuration = getTotalDuration();
		support.firePropertyChange(
				"ageOfManDuration", 
				this.ageOfManDuration, 
				this.ageOfManDuration = ageOfManDuration
		);
		support.firePropertyChange(
				"totalDuration", 
				oldTotalDuration, 
				getTotalDuration()
		);
	}
	
	public long getTotalDuration() {
		return this.ageOfAnimalsDuration + this.ageOfEarthDuration + this.ageOfManDuration + this.ageOfPlantsDuration;
	}

	public int getSeaLevel() {
		return seaLevel;
	}

	public void setSeaLevel(int seaLevel) {
		support.firePropertyChange(
				"seaLevel", 
				this.seaLevel, 
				this.seaLevel = seaLevel
		);
		
	}

	public List<TerrainMaterialTypeWeight> getTerrainTypeWeights() {
		return this.terrainTypeWeights;
	}
	
	public void setTerrainTypeWeights(
			List<TerrainMaterialTypeWeight> terrainTypeWeights) {
		this.terrainTypeWeights = terrainTypeWeights;
	}

	public void addPropertyChangeListener( PropertyChangeListener listener ) {
		this.support.addPropertyChangeListener(listener);
	}
	
	public void removePropertyChangeListener( PropertyChangeListener listener ) {
		this.support.removePropertyChangeListener(listener);
	}
}
